/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jogl2.pkg0.project;

/**
 *
 * @author Peb
 */
import java.awt.Component;
import java.awt.Frame;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GL2ES1;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.fixedfunc.GLLightingFunc;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.GLUquadric;


import com.jogamp.opengl.util.awt.TextRenderer;

import rnavizexperimentation.*;


import com.jogamp.opengl.util.Animator;
import java.awt.Color;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.MouseMotionListener;
import java.util.LinkedList;

/**
 * ported to JOGL 2.0 by Julien Gouesse (http://tuer.sourceforge.net)
 */
public class JOGL_2Dv3 implements GLEventListener, KeyListener {

    float rotateT = 0.0f;
    float cameraDistance = 250;
    float cameraPosX = 0;
    float cameraPosY = 0;
    int move = 0;
    private int startList;
    static GLU glu = new GLU();
    static GLCanvas canvas = new GLCanvas();
    static Frame frame = new Frame("Jogl Quad drawing");
    static Animator animator = new Animator(canvas);
//    static Font font = new Font("Serif", Font.PLAIN, 12);
    static Font font = new Font("Serif", Font.PLAIN, 72);
//    TextRenderer renderer = new TextRenderer(new Font("Serif", Font.PLAIN, 72), true, true);
    TextRenderer textRenderer = new TextRenderer((font), true, true);

    public void display(GLAutoDrawable gLDrawable) {
        final GL2 gl = gLDrawable.getGL().getGL2();
        gl.glClear(GL.GL_COLOR_BUFFER_BIT);
        gl.glClear(GL.GL_DEPTH_BUFFER_BIT);

        // tegn coordinatsystem
//        drawCoordinateSys(gl);

        gl.glLoadIdentity();


// the set camera thingy
//
//        gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
//        gl.glLoadIdentity();
//        float widthHeightRatio = 1.0f;
//
//
//        glu.gluPerspective(45, widthHeightRatio, 1, 1000);
//        glu.gluLookAt(cameraPosX, cameraPosY, cameraDistance, 0, 0, 0, 0, 1, 0);
//
//        gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
//        gl.glLoadIdentity();

// End camera thingy


//        gl.glColor3f(1.0f, 1.0f, 1.0f);   // set the color of the quad
//        GLUquadric earth = glu.gluNewQuadric();
//        glu.gluQuadricDrawStyle(earth, GLU.GLU_FILL);
//        glu.gluQuadricNormals(earth, GLU.GLU_NONE);
//        glu.gluQuadricOrientation(earth, GLU.GLU_OUTSIDE);



//        gl.glScalef(-10.0f, -1.0f, 0.0f);



//        gl.glBegin(GL2.GL_TRIANGLE_FAN);
//        gl.glColor3f(1.0f, 1.0f, 1.0f);   // set the color of the quad
//        gl.glVertex3f(-2, -2, 0);       // Top Right
//        gl.glVertex3f(+2, -2, 0);      // Bottom Right
//        gl.glVertex3f(0, 20, 0);     // Bottom Left
//        gl.glEnd();





//        gl.glTranslatef(-20.0f, 0.0f, -135.0f);

        // rotate on the three axis
//        gl.glRotatef(rotateT, 1.0f, 0.0f, 0.0f);
//        gl.glRotatef(rotateT, 0.0f, 1.0f, 0.0f);
//        gl.glRotatef(rotateT, 0.0f, 0.0f, 1.0f);

//         Draw A Quad
//        gl.glBegin(GL2.GL_QUADS);
//        gl.glColor3f(1.0f, 1.0f, 1.0f);   // set the color of the quad
//        gl.glVertex3f(-1.0f, 1.0f, 0.0f);      // Top Left
//        gl.glVertex3f(1.0f, 1.0f, 0.0f);       // Top Right
//        gl.glVertex3f(1.0f, -1.0f, 0.0f);      // Bottom Right
//        gl.glVertex3f(-1.0f, -1.0f, 0.0f);     // Bottom Left
//         Done Drawing The Quad
//        gl.glEnd();




//        gl.glPushMatrix();
//        gl.glBegin(GL.GL_TRIANGLES);              // Begin drawing triangles
//        gl.glTranslatef(-1.5f,1.5f,-8.0f);        // Move left 1.5 units, up 1.5 units, and back 8 units







//================================






//        gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);


        gl.glLoadIdentity(); //reset instillinger bla position for gl objektet


        textRenderer.setColor(Color.WHITE);

        textRenderer.beginRendering(800, 800);


        gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);


//        gl.glTranslatef(0.0f,0.0f, -335.0f);
//        gl.glScalef(0.5f, 0.5f, 0.0f);
//        gl.glPushMatrix();
        
        int x= 0;

        for (Point2D_int item : circleCoordinates) {

//            Point2D_int item = circleCoordinates[0];

         gl.glLoadIdentity(); 




                  gl.glTranslatef(item.getX() + move, item.getY() + move, 0);

                          gl.glRotatef(rotateT, 0, 0, 1);

        textRenderer.draw("A", 0, 0);

        textRenderer.flush();
        




//            textRenderer.draw3D("A", 1.0f,1.0f,0.0f, 3.0f);
        }

//        for (Point2D_int item : pointCoordinates) {
//            textRenderer.draw("d", item.getX() + move, item.getY() + move);
//        }



//        textRenderer.flush();
//        gl.glPopMatrix();


        textRenderer.endRendering();

//        rotateT += 1.1f;
//        move += 2;

//================================



//        gl.glEnd();                               // Finish drawing triangles
//        gl.glPopMatrix();




    }
// GetKnotArray (get the sequence number of the two 
//--------------------------------------------------------------------------------------------------------    
    private static Knot[] knotArray;
    static char[] sequence;
    static char[] knots;
    static LinkedList<Knot> edges;

    public static Knot[] getKnotArray() {

        InputHandler inp = new InputHandler();
        Structure si = inp.smallInput();
        sequence = si.getBaseSequence();
        knots = si.getDotSequence();

        edges = new LinkedList<Knot>();
        LinkedList<Knot> normalKnots = new LinkedList<Knot>();
        LinkedList<Knot> pseudoKnots = new LinkedList<Knot>();

        for (int i = 0; i < knots.length; i++) {
//            int x = 10 * i;
            if (knots[i] == '(') {
                Base n = new Base(i, sequence[i]);
                normalKnots.add(new Knot(new Base(i, sequence[i])));
                //drawArc(x, 100, 100, g2);
            }
            if (knots[i] == '[') {
                Base n = new Base(i, sequence[i]);
                pseudoKnots.add(new Knot(new Base(i, sequence[i])));
            }
            if (knots[i] == ')') {
                Base n = new Base(i, sequence[i]);
                Knot e = normalKnots.pop();
                e.setB2(n);
                edges.add(e);
            }
            if (knots[i] == ']') {
                Base n = new Base(i, sequence[i]);
                Knot e = pseudoKnots.pop();
                e.setB2(n);
                edges.add(e);
            }
        }


        while (!edges.isEmpty()) {
            Knot e = edges.pop();
            System.out.println(e.getB1().getPosition() + " - "
                    + e.getB1().getNucleotide() + "====" + e.getB2().getPosition() + " - " + e.getB2().getNucleotide());

//            int b1X = e.getB1().getX();
//            int e2X = e.getB2().getX();
//            drawArc(b1X,(e2X-b1X),100,g2);

        }


        return knotArray;
    }
//--------------------------------------------------------------------------------------------------------    
    private static Point2D_int[] circleCoordinates;

    public static Point2D_int[] calculateCoordCircle(int originx, int originy, int numberOfPoints, int radius) {

        circleCoordinates = new Point2D_int[numberOfPoints];

        for (int i = 0; i < numberOfPoints; i++) {
// Formlen for omregning er altså:  radianer = (2π/360) * grader
            double t = 2 * Math.PI * i / numberOfPoints;
            int x = (int) Math.round(originx + radius * Math.cos(t));
            int y = (int) Math.round(originy + radius * Math.sin(t));
            Point2D_int point = new Point2D_int(x, y);
            circleCoordinates[i] = point;
        }
        return circleCoordinates;
    }
//--------------------------------------------------------------------------------------------------------    
    private static final int NUMBEROFTEXTS = 1000;
    private static Point2D_int[] pointCoordinates = new Point2D_int[NUMBEROFTEXTS];

    public static void initCoordArray() {

        for (int x = 0; x < pointCoordinates.length; x++) {
            Point2D_int p = new Point2D_int((int) (Math.random() * 600), (int) (Math.random() * 600));
            pointCoordinates[x] = p;
        }
    }
    //--------------------------------------------------------------------------------------------------------    
    private static Point2D_int_wColor[] pointCoordinatesWColor = new Point2D_int_wColor[NUMBEROFTEXTS];

    public static void initCoordArrayWColor() {

        for (int x = 0; x < pointCoordinatesWColor.length; x++) {
            Point2D_int_wColor p = new Point2D_int_wColor(
                    new RandomFloatColor((float) Math.random(), (float) Math.random(), (float) Math.random()),
                    (int) (Math.random() * 600) - 300, (int) (Math.random() * 600) - 300);
            pointCoordinatesWColor[x] = p;
        }
    }
    //--------------------------------------------------------------------------------------------------------   

    public void updateMouseMovement(Point updatedMouseMovement) {
//        cameraPosX += (float)updatedMouseMovement.x;
//        System.out.println(mouseMovement.x + ", " + mouseMovement.y);
        cameraPosX += (float) updatedMouseMovement.x;
        cameraPosY += (float) updatedMouseMovement.y;

        System.out.println(updatedMouseMovement.x + ", " + updatedMouseMovement.y);

    }

    //--------------------------------------------------------------------------------------------------------    
    public static void drawCoordinateSys(GL2 gl) {

        gl.glLoadIdentity();
        gl.glBegin(GL2.GL_LINES);

        gl.glColor3f(1.0f, 0.0f, 0.0f);   // set the color of x
        gl.glVertex3f(-100, 0, 0);
        gl.glVertex3f(+100, 0, 0);

        gl.glColor3f(0.0f, 0.0f, 1.0f);   // set the color of y
        gl.glVertex3f(0, -100, 0);
        gl.glVertex3f(0, +100, 0);

        gl.glColor3f(0.0f, 1.0f, 0.0f);   // set the color of z
        gl.glVertex3f(0, 0, -100);
        gl.glVertex3f(0, 0, +100);

        gl.glEnd();
    }

    //--------------------------------------------------------------------------------------------------------    
    public void displayChanged(GLAutoDrawable gLDrawable, boolean modeChanged, boolean deviceChanged) {
    }

    public void init(GLAutoDrawable gLDrawable) {
        GL2 gl = gLDrawable.getGL().getGL2();
//        gl.glShadeModel(GLLightingFunc.GL_SMOOTH);
//        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//        gl.glClearDepth(1.0f);


        gl.glDisable(GL.GL_DEPTH_TEST);

//        gl.glEnable(GL.GL_DEPTH_TEST);
//        gl.glDepthFunc(GL.GL_LEQUAL);
//        gl.glHint(GL2ES1.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);


        ((Component) gLDrawable).addKeyListener(this);

        // ------ MousecontrollerObject

//        ControllerMouseClickMovement_scale controllerMouseClickMovement_scale = new ControllerMouseClickMovement_scale(this);

//        ((Component) gLDrawable).addMouseListener(controllerMouseClickMovement_scale);
//        ((Component) gLDrawable).addMouseMotionListener(controllerMouseClickMovement_scale);



    }

    public void reshape(GLAutoDrawable gLDrawable, int x, int y, int width, int height) {
        GL2 gl = gLDrawable.getGL().getGL2();
        if (height <= 0) {
            height = 1;
        }
        float h = (float) width / (float) height;


        gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
        gl.glLoadIdentity();

        glu.gluPerspective(45.0f, h, 1.0, 1000.0);

        gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
        gl.glLoadIdentity();
    }

    public void keyPressed(KeyEvent e) {

        if (e.getKeyCode() == KeyEvent.VK_Z) {
            cameraDistance += 3.0f;
        }
        if (e.getKeyCode() == KeyEvent.VK_A) {
            cameraDistance -= 3.0f;
        }
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            cameraPosX -= 3.0f;
        }
        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            cameraPosX += 3.0f;
        }
        if (e.getKeyCode() == KeyEvent.VK_DOWN) {
            cameraDistance -= 5.0f;
        }
        if (e.getKeyCode() == KeyEvent.VK_UP) {
            cameraDistance += 5.0f;
            System.out.println("der");
        }

        if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
            exit();
        }




    }

    public void keyReleased(KeyEvent e) {
    }

    public void keyTyped(KeyEvent e) {
    }

    public static void exit() {
        animator.stop();
        frame.dispose();
        System.exit(0);
    }

    public static void main(String[] args) {
        canvas.addGLEventListener(new JOGL_2Dv3());
        frame.add(canvas);
        frame.setSize(800, 800);
//        frame.setUndecorated(true);
//        frame.setExtendedState(Frame.MAXIMIZED_BOTH);
        frame.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                exit();
            }
        });


        initCoordArray();
        initCoordArrayWColor();
        calculateCoordCircle(400, 400, 20, 400);

//        getKnotArray();

        frame.setVisible(true);
        animator.start();
        canvas.requestFocus();
    }

    public void dispose(GLAutoDrawable gLDrawable) {
        // do nothing
    }
}